# Konwencja nazewnicza:
# X - przestrzen przeszukiwan
# XS - sekwencja punktow (moze byc pusta)
# U - liczba "losowa"
# US - sekwencja liczb losowych (moze byc pusta)

# zmienne globalne:
#problem #potrzebna nam informacja o klasie rozwiazywanego problemu
trace <- list() #slad punktow"
costs <- vector() #koszty poszczegolnych punktow sladu
open <- vector() #informacja czy poszczegolne pty sladu sa otwarte
random <- c() #liczby "losowe"


#model OOP w tym jezyku wywrocony jest na druga strone
#ponizej definicje metod generycznych, ktorych specjalizacje musza byc zaimplementowane
#dla wszystkich klas problemu obslugiwanych przez nasza metode
#(w tym przypadku 'sort' i 'tsp')

#init <- function(x,...) UseMethod("init")
#init.default <- function(x,...) print("metoda inicjalizacyjna nie zostala okreslona dla tej klasy problemu")

#heuristic <- function(x,...) UseMethod("heuristic")
#heuristic.default <- function(x,...) print("funkcja heurystyczna nie zostala okreslona dla tej klasy problemu")

#cost <- function(x,...) UseMethod("cost")
#cost.default <- function(x,...) print("funkcja kosztu nie zostala okreslona dla tej klasy problemu")

#generate <- function(x,...) UseMethod("generate")
#generate.default <- function(x,...) print("metoda generacji punktow nie zostala okreslona dla tej klasy problemu")



# zapis do sladu punktow
push<-function(XS) {
	trace <<- c(trace,XS)
	#print(XS)
	newcosts <-vector()
	newopen <- rep(TRUE,length(XS))
	for(i in 1:length(XS)) {
		newcosts[i]<-cost(XS[[i]])+heuristic(XS[[i]])
	}
	costs <<- c(costs,newcosts)
	open <<- c(open,newopen)
}



# odczyt ze sladu punktow co najwyzej n elementow
# Inf oznacza cala historie
pop<-function(n=Inf) {
  len <- length(trace)
  return(trace[max(len-n+1,1):len])
}

# inicjacja sladu
trace_init<-function(){
	trace <<- list()
	costs <<- vector()
	open <<- vector()
}

UG<-function() {
  return(runif(1,min=0,max=1))
}

# inicjacja - generuje sekwencje punktow na podstawie 
# liczb losowych
op_init<-function(UG){
	x <- UG
	#attr(x,'class')<-problem
	return(init(x))
}

# selekcja - generuje podsekwencje argumentu, posilkujac sie
# sekwencja liczb losowych
op_select<-function(XS, UG) {
  return(XS)
}

# generacja - generuje sekwencje punktow na podstawie 
# innej sekwencji punktow oraz liczb losowych
op_generate<-function(XS,UG) {
  return(XS)
}

# operator zagregowany - generuje sekwencje punktow na podstawie 
# innej sekwencji punktow oraz liczb losowych
op_agr<-function(XS,UG,op_select, op_generate)
{
  return (op_generate(op_select(XS, UG),UG))
}

# kryterium zatrzymania obserwuje punkty z historii, moze przyjmowac
# argumenty ktorych nie sposob przewidziec z gory
# zwraca wartosc logiczna
stop_criterion<-function(XS, stop_args=NULL) {
  	return(TRUE)
}

#algorytm przeszukiwania 
search<-function(op_init, op_select,op_generate, stop_criterion, UG)
{
  trace_init()
  push(op_init(UG))
  while (!stop_criterion(pop())) {
    push(op_agr(pop(), UG,op_select,op_generate))
  }
	
}
